package com.qinggeng.project.system.service.impl;

import com.qinggeng.common.enums.CommonEnum;
import com.qinggeng.common.enums.ShowTypeEnum;
import com.qinggeng.common.exception.CustomException;
import com.qinggeng.common.utils.DateUtils;
import com.qinggeng.framework.config.mq.dto.MessageBeatDTO;
import com.qinggeng.project.api.dto.BeatNewsDto;
import com.qinggeng.project.api.dto.BeatOrdersInfoDto;
import com.qinggeng.project.api.dto.UserBeatDto;
import com.qinggeng.project.system.domain.Orders;
import com.qinggeng.project.system.domain.OrdersGoods;
import com.qinggeng.project.system.domain.UserBeat;
import com.qinggeng.project.system.domain.UserBeatMessageRecord;
import com.qinggeng.project.system.mapper.GoodsKeepMapper;
import com.qinggeng.project.system.mapper.OrdersGoodsMapper;
import com.qinggeng.project.system.mapper.UserBeatMapper;
import com.qinggeng.project.system.mapper.UserBeatMessageRecordMapper;
import com.qinggeng.project.system.service.IOrdersService;
import com.qinggeng.project.system.service.MQSendService;
import com.qinggeng.project.system.service.UserBeatService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * @author 吴鹏飞
 * @date 2020/10/29
 * 用户捶一捶业务记录实现
 */
@Slf4j
@Service
public class UserBeatServiceImpl implements UserBeatService {
    @Resource
    private UserBeatMapper userBeatMapper;
    @Autowired
    private IOrdersService ordersService;
    @Autowired
    private MQSendService mqSendService;
    @Resource
    private OrdersGoodsMapper ordersGoodsMapper;
    @Resource
    private GoodsKeepMapper goodsKeepMapper;

    @Resource
    private RedissonClient redissonClient;

    @Resource
    private UserBeatMessageRecordMapper userBeatMessageRecordMapper;

    @Resource
    private DataSourceTransactionManager transactionManager;

    @Resource
    private TransactionDefinition transactionDefinition;

    private static final String LOCK_BEAT_ID_ = "lock_beat_id_";
    /**
     * 查询所有符合条件的用户记录
     * @param userBeatDto
     * @return
     */
    @Override
    public List<UserBeatDto> selectUserBeatList(UserBeatDto userBeatDto) {
        return userBeatMapper.selectUserBeatList(userBeatDto);
    }

    /**
     * 更新捶成时间
     * @param ordersId
     */
    @Override
    public void updateUserBeatByOrdersId(Long ordersId) {
        userBeatMapper.updateUserBeatByOrdersId(ordersId);
    }

    /**
     * 根据用户id查询当天所捶次数
     * @param userId
     * @return
     */
    @Override
    public int selectCountTodayByUserId(Long userId) {
        return userBeatMapper.selectCountTodayByUserId(userId);
    }
    /**
     * 根据捶成条件查询所有捶成记录
     * @param beatInto
     * @return
     */
    @Override
    public List<BeatNewsDto> selectUserBeatSuccessList(String beatInto) {
        return userBeatMapper.selectUserBeatSuccessList(beatInto);
    }
    /**
     * 根据订单id获取用户捶一捶和本人信息
     * @param ordersId
     * @return
     */
    @Override
    public BeatOrdersInfoDto selectUserBeatAndUserInfoByOrdersId(Long ordersId) {
        return userBeatMapper.selectUserBeatAndUserInfoByOrdersId(ordersId);
    }
    /**
     * 查询超时未捶成用户捶一捶记录
     */
    @Override
    public List<UserBeat> selectOutTimeUserBeatList() {
        return userBeatMapper.selectOutTimeUserBeatList();
    }
    /**
     * 更新用户捶一捶信息
     * @param userBeat
     */
    @Override
    public int updateUserBeat(UserBeat userBeat) {
        return userBeatMapper.updateUserBeat(userBeat);
    }
    /**
     * 根据用户id查询当天所捶的商品id集合
     * @param userId
     * @return
     */
    @Override
    public List<Long> selectMainCategorysByNowAndUserId(Long userId) {
        return userBeatMapper.selectMainCategorysByNowAndUserId(userId);
    }

    /**
     * 根据订单id查询捶一捶信息
     * @param ordersId
     * @return
     */
    @Override
    public UserBeat selectUserBeatByOrdersId(Long ordersId) {
        return userBeatMapper.selectUserBeatByOrdersId(ordersId);
    }

    /**
     * 捶一捶失败处理
     * @param messageBeatDto
     */
    @Override
    @Transactional
    public void updateUserBeatForFail(MessageBeatDTO messageBeatDto) {
        if (messageBeatDto == null){
            throw new CustomException("捶一捶消息实体不存在");
        }

        RLock lock = redissonClient.getLock(LOCK_BEAT_ID_ + messageBeatDto.getId());
        lock.lock();
        log.info("-----捶一捶失败处理开始-----");
        try {

            Example example = new Example(UserBeatMessageRecord.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("messageId",messageBeatDto.getMessageId());
            UserBeatMessageRecord userBeatMessageRecord = userBeatMessageRecordMapper.selectOneByExample(example);
            if (userBeatMessageRecord != null){
                return;
            }
            userBeatMessageRecord = new UserBeatMessageRecord();
            userBeatMessageRecord.setBeatId(messageBeatDto.getId());
            userBeatMessageRecord.setDelayTime(messageBeatDto.getDelayTime());
            userBeatMessageRecord.setMessageId(messageBeatDto.getMessageId());
            userBeatMessageRecord.setCreateTime(new Date());
            userBeatMessageRecordMapper.insertSelective(userBeatMessageRecord);


            UserBeat userBeat = userBeatMapper.selectUserBeatById(messageBeatDto.getId());
            if (userBeat == null){
                throw new CustomException("用户捶一捶信息不存在");
            }
            //是进行中修改状态为失败 2进行中 0 失败
            if (!"2".equals(userBeat.getBeatInto())){
                return;
            }

            try {
                List<OrdersGoods> ordersGoodsList = ordersGoodsMapper.selectOrderGoodListByOrdersId(userBeat.getOrdersId());
                Orders orders = ordersService.selectOrdersById(userBeat.getOrdersId());
                for (OrdersGoods ordersGoods : ordersGoodsList) {
                    try {
                        //                redisTemplate.opsForValue().increment(KEEP_OF_GOODS + ordersGoods.getGoodsId(), ordersGoods.getGoodsNum());
                        goodsKeepMapper.addKeepNum(ordersGoods.getGoodsId(),orders.getShopId(),ordersGoods.getGoodsNum());
                    } catch (Exception e) {
                        log.error("库存恢复失败：" + e.getMessage());
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            userBeat.setBeatInto("0");
            userBeatMapper.updateUserBeat(userBeat);
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    @Override
    public boolean receiveGoods(Long ordersId) {
        Orders orders = ordersService.selectOrdersById(ordersId);
        if (orders == null) {
            throw new CustomException("订单不存在", ShowTypeEnum.用户.getValue());
        }
        if (orders.getDelFlag().equals("0")) {
            throw new CustomException("已领取");
        }
        TransactionStatus transaction = null;
        try {
            transaction = transactionManager.getTransaction(transactionDefinition);
            //更新订单状态为未删除状态,打印为可打印
            orders.setDelFlag("0");
            orders.setPrintStatus(CommonEnum.STATUS_10.getValue());
            ordersService.updateOrders(orders);

            UserBeat userBeat = userBeatMapper.selectUserBeatByOrdersId(ordersId);
            //设置为已领取
            userBeat.setReceive("1");
            userBeat.setReceiveTime(new Date());
            userBeatMapper.updateUserBeat(userBeat);
            transactionManager.commit(transaction);
        } catch (Exception e) {
            transactionManager.rollback(transaction);
            e.printStackTrace();
        }

        //自动接单
        mqSendService.sendOrdersAutoTakeAsynMessage(orders.getOrdersNo());
        //发送订单自动发货消息
        //mqSendService.sendOrdersAutoShipDelayMessage(orders.getOrdersNo());

        return true;
    }

    /**
     * 查询用户捶一捶记录
     *
     * @param id 用户捶一捶记录ID
     * @return 用户捶一捶记录
     */
    @Override
    public UserBeat selectUserBeatById(Long id)
    {
        return userBeatMapper.selectUserBeatById(id);
    }

    /**
     * 查询用户捶一捶记录列表
     *
     * @param userBeat 用户捶一捶记录
     * @return 用户捶一捶记录
     */
    @Override
    public List<UserBeat> selectUserBeatList(UserBeat userBeat)
    {
        return userBeatMapper.selectAnotherUserBeatList(userBeat);
    }


    /**
     * 批量删除用户捶一捶记录
     *
     * @param ids 需要删除的用户捶一捶记录ID
     * @return 结果
     */
    @Override
    public int deleteUserBeatByIds(Long[] ids)
    {
        return userBeatMapper.deleteUserBeatByIds(ids);
    }

    /**
     * 删除用户捶一捶记录信息
     *
     * @param id 用户捶一捶记录ID
     * @return 结果
     */
    @Override
    public int deleteUserBeatById(Long id)
    {
        return userBeatMapper.deleteUserBeatById(id);
    }
}
